/************************************************
 * Copyright (c) 2007 ~ 2010 
 * All rights reserved.
 * Version   : 1.0
 * Author    : lengsh@alibaba-inc.com 
 * Date      : 2008.12.20
 *
 *  g++ -o Regex_KV_Mapping.cc -g3 `pkg-config --cflags --libs glib-2.0` -I/usr/include/glib-2.0  -lglib-2.0 
 *
 */
#ifndef  _REGEX_KV_MAPPING_H__
#define  _REGEX_KV_MAPPING_H__

#include <string.h>
#include <iostream>
#include <glib.h>
#include <stdlib.h>
#include "Debug.h"
using namespace std;
class MappingIndex {
	public:
	MappingIndex(int imax):m_iMax(imax+1) 
	{
		m_pInt = new int[m_iMax];
                for(int i=0; i<m_iMax; i++)
                   m_pInt[i] = -1;
	}
	~MappingIndex() 
	{
		delete []m_pInt;
	}
	
	protected:
		const int m_iMax;
		int *m_pInt;
        public:
		bool Check()
		{
			for(int i=0; i<m_iMax; i++)
				if( m_pInt[i] ==  -1)
					return false;
			return true;
		}

		int AddLines(const char *src,const int ikey)
		{
                        DEBUG2(src, ikey);
			int ic = 0;
			char **columns = g_strsplit(src, ",", -1);
                        int columns_num =  g_strv_length(columns);
                        for(int i=0; i< columns_num ; i++ )
			{
				char **fields = g_strsplit(columns[i], "-", -1);
				int fields_num = g_strv_length(fields);
				if( fields_num == 2)
				{  // 3-6
					int min = atoi(fields[0]);
					int max = atoi(fields[1]);
					int tmp = min;
					if( max < min)
					{
						min = max;
						max = tmp;
					}  
					if(min < 0 || max > m_iMax )
					{
						cout<<"error"<<endl;
                                                DEBUG6("from ",min, "to ", max, "but iMax=", m_iMax);
                                                g_strfreev(fields);
                                                g_strfreev(columns);
						return 0;
					}
					for(; min<= max; min++)
                                        {
                                                m_pInt[min ] = ikey;
                                                ic++;
                                        }
				}         
				else if( fields_num == 1 )
				{ 
					int iv =  atoi( fields[0] );
					if(iv>=0 && iv< m_iMax) 
					{
						m_pInt[iv] =  ikey;
						ic++;
					}
				}
				g_strfreev(fields);
			}
			g_strfreev (columns);
			return ic;
		}

		unsigned int GetKeybyNumber(const int idx )
		{
			//assert( idx>= Hash_Min && idx <= Hash_Max);
        		return (unsigned int)m_pInt[idx%(m_iMax+1)]; 
 /*                        
			if( idx >= 0 && idx <  m_iMax )
				return (unsigned int)m_pInt[idx ]; 
                        else
                        {
                           DEBUG2(idx, " is out range [0,", m_iMax);
                           abort();
                        }
*/
		}

		void Print()
		{
                    for(int i=0; i< m_iMax; i++)
                      cout<< i << " --> "<< m_pInt[i] <<endl;
		} 

};

#endif  // _REGEX_KV_MAPPING_H__

/*
int main(int argc , char *argv[])
{
	MappingIndex helper(128);
        helper.AddLines("0,1-10", 0);
        helper.AddLines("11-124", 1);
        if(!helper.Check())
		cout << "error"<<endl;

	cout << helper.GetKeybyNumber(10) << endl;        

	MappingIndex h1(32);
	h1.AddLines("0,1-10", 0);
	h1.AddLines("11-32", 1);
	if(!h1.Check())
		cout << "error"<<endl;

	cout << h1.GetKeybyNumber(20) << endl;        
	cout << h1.GetKeybyNumber(120) << endl;        

	return 0;
}
*/
